package com.niodata.dp.web.module.base;

import com.niodata.dp.core.exception.DpException;
import com.niodata.dp.core.exception.ErrorCodes;
import com.niodata.dp.core.security.OperationAccessControl;
import com.niodata.dp.log.LogUtil;
import com.niodata.dp.util.TimeUtil;
import com.niodata.dp.web.PageInfo;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * Created by ndp on 17-3-6.
 */
@ControllerAdvice
public class BaseController {

  private static final Logger logger = Logger.getLogger(BaseController.class);
  @Autowired
  @Qualifier("DefaultAccessControl")
  protected OperationAccessControl operationAccessControl;

  /**
   * 异常处理.
   */
  @ExceptionHandler
  @ResponseBody
  public Map<String, Object> exceptionHandle(Exception ex, HttpServletResponse response) {
    LogUtil.logStackTrace(logger, ex);
    if (ex.getCause() != null && DpException.class.isAssignableFrom(ex.getCause().getClass())) {
      ex = (Exception) ex.getCause();
    }
    if (DpException.class.isAssignableFrom(ex.getClass())) {
      DpException dpException = (DpException) ex;
      //response.setStatus(dpException.errorCode());
      return getResultMap(dpException.errorCode(), null,
            ex.getMessage(), null);
    } else {
      //response.setStatus(500);
      return getResultMap(ErrorCodes.SYSTEM_EXCEPTION, null,
            ex.getMessage() == null ? ErrorCodes.getErrorMsg(ErrorCodes.SYSTEM_EXCEPTION)
                  : ex.getMessage(), null);
    }
  }

  protected Map<String, Object> getResult(Object object) {
    return getResultMap(null, object, null, null);
  }


  protected Map<String, Object> getResult(Object object, Map<String, Object> extraMap) {
    return getResultMap(null, object, null, extraMap);
  }

  protected Map<String, Object> getPagedResult(List dataList, PageInfo pageInfo) {
    Map<String, Object> map = this.getResult(dataList);
    map.put("pageIndex", pageInfo.getPageIndex());
    map.put("start", pageInfo.getStart());
    map.put("stop", pageInfo.getStop());
    map.put("hasMore", pageInfo.isHasMore());
    return map;
  }

  protected Map<String, Object> getPagedResult(List dataList,
        int pageIndex,
        int offset,
        int count,
        boolean hasMore) {
    Map<String, Object> map = this.getResult(dataList);
    map.put("pageIndex", pageIndex);
    map.put("start", offset);
    map.put("stop", offset + count);
    map.put("hasMore", hasMore);
    return map;

  }

  protected Map<String, Object> getSeqPagedResult(List dataList, PageInfo pageInfo) {
    Map<String, Object> map = this.getResult(dataList);
    map.put("maxSeq", pageInfo.getMaxSeq());
    map.put("minSeq", pageInfo.getMinSeq());
    map.put("pageIndex", pageInfo.getPageIndex());
    map.put("start", pageInfo.getStart());
    map.put("stop", pageInfo.getStop());
    map.put("hasMore", pageInfo.isHasMore());
    return map;
  }


  protected Map<String, Object> getError(int errCode, String errMsg) {
    return getResultMap(errCode, null,
          errMsg == null ? ErrorCodes.getErrorMsg(errCode) : errMsg, null);
  }

  private Map<String, Object> getResultMap(Integer code,
        Object data,
        String msg,
        Map<String, Object> extraMap) {
    String currentTime = TimeUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss");
    Map<String, Object> map = new HashMap<String, Object>();
    map.put("currentTime", currentTime);
    if (code == null || code.equals(200)) {
      map.put("code", 200);
      map.put("data", data);

    } else {
      map.put("code", code);
      map.put("msg", msg);
    }
    if (extraMap != null && !extraMap.isEmpty()) {
      map.putAll(extraMap);
    }
    return map;
  }

}
